﻿using SvGame.Objects;
using System.Numerics;
using System.Security.Cryptography;
using System.Xml.Linq;

namespace SvGame.Logic;

public static partial class GameLogic
{
    public static int PerformAct(this IRole me, string configId)
    {
        if (!ConfPerform.TryGetValue(configId, out var conf))
        {
            loger.Error($"PerformAct err 缺少配置 {me.Name}[{me.Uid}] configId:{configId}");
            return 1;
        }
        // 判断cd时间
        // todo PerformAct 研发阶段去掉了冷却限制
        //if (conf.CoolDown > 0 && me.IsCd(conf.Id))
        //{
        //    return me.MessageError($"你现在还不能使用『{conf.Name}』！");
        //}

        var PerformFunc = (EPerformFunc)conf.PerformFunc;
        switch (PerformFunc)
        {
            case EPerformFunc.自疗:
                return Perform自疗(me, conf);
            case EPerformFunc.敌单连招:
                {
                    var opp = me.GetAttackTarget();
                    if (opp == null)
                    {
                        return me.MessageError($"你要对谁施展这一招『{conf.Name}』？");
                    }
                    return Perform敌单连招(me, conf, opp);
                }
            case EPerformFunc.敌单内外功:
                {
                    var opp = me.GetAttackTarget();
                    if (opp == null)
                    {
                        return me.MessageError($"你要对谁施展这一招『{conf.Name}』？");
                    }
                    return Perform敌单内外功(me, conf, opp);
                }
            case EPerformFunc.敌单法术:
                {
                    var opp = me.GetAttackTarget();
                    if (opp == null)
                    {
                        return me.MessageError($"你要对谁施展这一招『{conf.Name}』？");
                    }
                    return Perform敌单法术(me, conf, opp);
                }
            case EPerformFunc.自状态:
                return Perform自状态(me, conf);
            default:
                break;
        }

        return 0;
    }
    public static int Perform自疗(this IRole me, ConfigPerform conf)
    {
        var PerformFuncSub = (EPerformFuncSub)conf.PerformFuncSub;
        switch (PerformFuncSub)
        {
            default:
                break;
        }

        // 招式前描述
        if (!conf.DescPre.IsNullOrEmpty())
        {
            MessageVisionCombat(conf.DescPre, me);
        }

        switch (PerformFuncSub)
        {
            case EPerformFuncSub.恢复气血:
                {
                    var usageLevel = me.UsageGetLevel(EUsageType.基本内功);
                    var diff = me.StatusEff.Kee - me.StatusCur.Kee;
                    var needForce = diff * 50 / usageLevel;
                    if (needForce < 1)
                    {
                        return me.MessageError($"你气血充足，不需要吸气。");
                    }
                    if (needForce > me.StatusCur.Force)
                    {
                        needForce = me.StatusCur.Force;
                    }
                    diff = needForce * usageLevel / 50;
                    me.ReceiveHealKee(diff);
                    me.UseProp(EPropType.Force, needForce);
                }
                break;
            case EPerformFuncSub.恢复精神:
                {
                    var usageLevel = me.UsageGetLevel(EUsageType.基本内功);
                    var diff = me.StatusEff.Sen - me.StatusCur.Sen;
                    var needForce = diff * 50 / usageLevel;
                    if (needForce < 1)
                    {
                        return me.MessageError($"你精神饱满，不需要吸气。");
                    }
                    if (needForce > me.StatusCur.Force)
                    {
                        needForce = me.StatusCur.Force;
                    }
                    diff = needForce * usageLevel / 50;
                    me.ReceiveHealSen(diff);
                    me.UseProp(EPropType.Force, needForce);
                }
                break;
            case EPerformFuncSub.恢复有效气血:
                {
                    if (me.StatusEff.Kee >= me.StatusMax.Kee)
                    {
                        return me.MessageError($"你气血圆满，不需要疗伤。");
                    }
                    if (me.StatusEff.Kee < me.StatusMax.Kee / 4)
                    {
                        return me.MessageError($"你已经受伤过重，只怕一运真气便有生命危险！");
                    }
                    var usageLevel = me.UsageGetLevel(EUsageType.基本内功);
                    me.ReceiveCuringKee(50 + usageLevel / 5);
                    // todo 消耗内力
                }
                break;
            case EPerformFuncSub.恢复有效精神:
                {
                    if (me.StatusEff.Sen >= me.StatusMax.Sen)
                    {
                        return me.MessageError($"你精神充足，不需要疗伤。");
                    }
                    if (me.StatusEff.Sen < me.StatusMax.Sen / 4)
                    {
                        return me.MessageError($"你已经心智迷失，无法集中精神念咒！");
                    }
                    var usageLevel = me.UsageGetLevel(EUsageType.基本法术);
                    me.ReceiveCuringSen(50 + usageLevel / 5);
                    // todo 消耗内力
                }
                break;
            default:
                break;
        }

        // 招式后描述
        if (!conf.DescEnd.IsNullOrEmpty())
        {
            MessageVisionCombat(conf.DescEnd, me);
        }

        me.Hp();

        return 0;
    }
    public static int Perform敌单连招(this IRole me, ConfigPerform conf, IRole opp)
    {
        // 招式前描述
        if (!conf.DescPre.IsNullOrEmpty())
        {
            MessageVisionCombat(conf.DescPre, me, opp);
        }

        var ActCountType = (EPerformFuncSub)conf.PerformFuncSub;
        // 施放连招
        switch (ActCountType)
        {
            case EPerformFuncSub.重复固定数目:
                if (conf.Acts.Count == 0 || conf.Args.Count == 0)
                {
                    loger.Error($"Perform敌单连招 {conf.Id} error 重复固定数目 未配置 Acts或ActCountArgs");
                    return 1;
                }
                {
                    var act = conf.Acts[0];
                    var actCount = conf.Args[0].ToInt();
                    for (int i = 0; i < actCount; i++)
                    {
                        Perform敌单连招Node(me, conf, opp, act);
                    }
                }
                break;
            case EPerformFuncSub.顺序列表数目:
                foreach (var act in conf.Acts)
                {
                    Perform敌单连招Node(me, conf, opp, act);
                }
                break;
            case EPerformFuncSub.重复技能等级总和除系数:
                if (conf.Acts.Count == 0 || conf.Args.Count < 2)
                {
                    loger.Error($"Perform敌单连招 {conf.Id} error 重复技能等级总和除系数 错误配置 Acts或ActCountArgs");
                    return 1;
                }
                {
                    var act = conf.Acts[0];
                    var 技能总等级 = 0;
                    var 技能系数 = conf.Args.Last().ToInt();
                    for (int i = 0; i < conf.Args.Count - 1; i++)
                    {
                        技能总等级 += me.SkillGetLevel(conf.Args[i]);
                    }
                    var actCount = 技能总等级 / 技能系数;
                    for (int i = 0; i < actCount; i++)
                    {
                        Perform敌单连招Node(me, conf, opp, act);
                    }
                }
                break;
            case EPerformFuncSub.顺序技能等级总和除系数:
                if (conf.Acts.Count == 0 || conf.Args.Count < 2)
                {
                    loger.Error($"Perform敌单连招 {conf.Id} error 顺序技能等级总和除系数 错误配置 Acts或ActCountArgs");
                    return 1;
                }
                {
                    var 技能总等级 = 0;
                    var 技能系数 = conf.Args.Last().ToInt();
                    for (int i = 0; i < conf.Args.Count - 1; i++)
                    {
                        技能总等级 += me.SkillGetLevel(conf.Args[i]);
                    }
                    var actCount = 技能总等级 / 技能系数;
                    actCount = Math.Min(actCount, conf.Acts.Count);
                    for (int i = 0; i < actCount; i++)
                    {
                        Perform敌单连招Node(me, conf, opp, conf.Acts[i]);
                    }
                }
                break;
            default:
                break;
        }
        // 施放连招完毕
        me.Comb.PerformActName = string.Empty;

        // 招式后描述
        if (!conf.DescEnd.IsNullOrEmpty())
        {
            MessageVisionCombat(conf.DescEnd, me, opp);
        }

        return 0;
    }
    public static void Perform敌单连招Node(IRole me, ConfigPerform conf, IRole opp, string act)
    {
        if (!ConfCbtAction.ContainsKey(act))
        {
            loger.Error($"Perform敌单连招 {conf.Id} error act:{act}");
            return;
        }
        me.Comb.PerformActName = act;
        me.DoAttack(opp, me.Comb.Weapon, EAttackType.Perform);
    }
}
